#include <iostream>
#include <string>
#include <thread>
#include <functional>
#include "tcp_api.h"

#define SERVER_IP     "127.0.0.1"
#define SERVER_PORT   8001


class CClientSpi : public CTcpSpi
{
public:
	CClientSpi(CTcpApi* api) :m_api(api) {}
	virtual void OnConnected(Session_t session)
	{
		printf("OnConnected:session_id=%d\n", session.nSessionID);
		std::string msg1 = "I am client,send times:" + std::to_string(nCout);
		m_api->Write(session, msg1.data(), msg1.size());
	}
	virtual void OnDisConnect(Session_t session)
	{
		printf("OnDisConnect:session_id=%d\n", session.nSessionID);
	}
	virtual void OnMessage(Session_t session, const std::string msg)
	{
		std::this_thread::sleep_for(std::chrono::seconds(1));
		nCout++;
		std::string msg1 = "I am client,send times:" + std::to_string(nCout);
		m_api->Write(session, msg1.data(), msg1.size());
		printf("client:%d send data,times=%lld\n", session.nSessionID, nCout);
	}
private:
	CTcpApi* m_api;
	int64_t nCout = 0;
};

class CServerSpi : public CTcpSpi
{
public:
	CServerSpi(CTcpApi* api) :m_api(api)
	{
		m_api->AddTimer(1, 1000, std::bind(&CServerSpi::OnTimer, this));
	}
	virtual void OnConnected(Session_t session)
	{
		printf("OnConnected:session_id=%d", session.nSessionID);
	}
	virtual void OnDisConnect(Session_t session)
	{
		printf("OnDisConnect:session_id=%d\n", session.nSessionID);
	}
	virtual void OnMessage(Session_t session, const std::string msg)
	{
		nCout++;
		printf("server recv from clientID[%d] data:[%s]\n", session.nSessionID, msg.c_str());
		m_api->Write(session, msg.data(), msg.size());
	}
	void OnTimer()
	{
		printf("测试定时器被调用\n");
	}
private:
	CTcpApi* m_api;
	int64_t nCout = 0;
};

//服务端测试
int main(int argc, char* argv[])
{
	auto api = new CTcpApi(1);
	auto client_spi = new CClientSpi(api);
	auto server_spi = new CServerSpi(api);
	api->RegisterSpi(server_spi, client_spi);
	api->StartServer(SERVER_PORT);
	api->StartConnect(SERVER_IP, SERVER_PORT,true);
	std::this_thread::sleep_for(std::chrono::seconds(3));
	while (true)
	{
		std::this_thread::sleep_for(std::chrono::seconds(1));
	}
	api->StopWork();
	if (client_spi)
	{
		delete client_spi;
	}
	if (server_spi)
	{
		delete server_spi;
	}
	if (api)
	{
		delete api;
	}
	return 0;
}